package com.xuecheng.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.base.exception.XueChengPlusException;
import com.xuecheng.base.model.PageParams;
import com.xuecheng.base.model.PageResult;
import com.xuecheng.content.mapper.*;
import com.xuecheng.content.model.dto.AddCourseDto;
import com.xuecheng.content.model.dto.CourseBaseInfoDto;
import com.xuecheng.content.model.dto.EditCourseDto;
import com.xuecheng.content.model.dto.QueryCourseParamsDto;
import com.xuecheng.content.model.po.*;
import com.xuecheng.content.service.CourseBaseInfoService;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

/**
 * 课程信息管理业务接口实现类
 */
@Service
public class CourseBaseInfoServiceImpl extends ServiceImpl<CourseBaseMapper, CourseBase> implements CourseBaseInfoService {

    @Autowired
    private CourseBaseMapper courseBaseMapper;

    @Autowired
    private CourseMarketMapper courseMarketMapper;

    @Autowired
    private CourseCategoryMapper courseCategoryMapper;

    @Autowired
    private TeachplanMapper teachplanMapper;

    @Autowired
    private CourseTeacherMapper courseTeacherMapper;

    /**
     * 课程查询实现
     *
     * @param pageParams        分页参数
     * @param queryCourseParams 条件参数
     * @return
     */
    @Override
    public PageResult<CourseBase> queryCourseBaseList(Long companyId, PageParams pageParams, QueryCourseParamsDto queryCourseParams) {
        // 1. 获取查询条件参数
        // 课程名称
        String courseName = queryCourseParams.getCourseName();
        // 审核状态
        String auditStatus = queryCourseParams.getAuditStatus();
        // 发布状态
        String publishStatus = queryCourseParams.getPublishStatus();

        // 2. 构建条件构造器
        LambdaQueryWrapper<CourseBase> queryWrapper = new LambdaQueryWrapper<>();
        // 构建查询条件，根据机构id查询
        queryWrapper.eq(CourseBase::getCompanyId, companyId);
        // 构建查询条件，根据课程名称模糊查询
        queryWrapper.like(StringUtils.isNotEmpty(courseName), CourseBase::getName, courseName);
        // 构建查询条件，根据课程审核状态查询
        queryWrapper.eq(StringUtils.isNotEmpty(auditStatus), CourseBase::getAuditStatus, auditStatus);
        // 构建查询条件，根据课程发布状态查询
        queryWrapper.eq(StringUtils.isNotEmpty(publishStatus), CourseBase::getStatus, publishStatus);
        // 构建查询条件，按照插入、更新时间降序
        queryWrapper
                .orderByDesc(CourseBase::getCreateDate);

        // 3. 构建分页构造器
        Page<CourseBase> page = new Page<>(pageParams.getPageNo(), pageParams.getPageSize());

        // 4. 查询数据库，获取结果
        Page<CourseBase> pageResult = courseBaseMapper.selectPage(page, queryWrapper);

        // 5. 获取数据列表
        List<CourseBase> list = pageResult.getRecords();
        // 6. 获取数据总数
        long total = pageResult.getTotal();

        // 7. 构建返回结果集
        PageResult<CourseBase> result = new PageResult<>(list, total, pageParams.getPageNo(), pageParams.getPageSize());

        // 8. 返回控制器结果
        return result;
    }

    /**
     * 添加课程基本信息
     *
     * @param companyId 教育机构id
     * @param dto       课程基本信息
     * @return 课程详细信息
     */
    @Transactional
    @Override
    public CourseBaseInfoDto createCourseBase(Long companyId, AddCourseDto dto) {
        // 1. 创建课程基本信息对象
        CourseBase courseBase = new CourseBase();
        // 拷贝数据
        BeanUtils.copyProperties(dto, courseBase);
        // 设置机构id
        courseBase.setCompanyId(companyId);

        // 2. 插入课程基本信息
        int courseBaseInsert = courseBaseMapper.insert(courseBase);
        // 判断课程基本信息是否插入成功
        if (courseBaseInsert != 1) throw new XueChengPlusException("新增课程基本信息失败");

        // 3. 获取刚刚插入成功的课程基本信息数据的id
        Long courseId = courseBase.getId();

        // 4. 创建课程营销信息对象
        CourseMarket courseMarket = new CourseMarket();
        // 拷贝数据
        BeanUtils.copyProperties(dto, courseMarket);
        // 设置id（与课程基本信息表的id为一对一关系）
        courseMarket.setId(courseId);
        // 5. 判断课程类型，若为收费课程，价格不可小于0
        if ("201001".equals(courseMarket.getCharge())) {
            if (courseMarket.getPrice() == null || courseMarket.getPrice() < 0) {
                XueChengPlusException.cast("您选择的是收费课程，价格不能为空或小于0");
            }
        }

        // 6. 插入课程营销信息
        int courseMarketInsert = courseMarketMapper.insert(courseMarket);
        // 判断课程营销信息是否插入成功
        if (courseMarketInsert != 1) throw new XueChengPlusException("新增课程营销信息失败");

        // 7. 返回添加的课程信息
        return getCourseBaseById(courseId);
    }

    /**
     * 根据课程id查询课程基础信息
     *
     * @param courseId 课程id
     * @return 详细课程信息
     */
    public CourseBaseInfoDto getCourseBaseById(Long courseId) {
        // 创建结果返回对象
        CourseBaseInfoDto courseBaseInfoDto = new CourseBaseInfoDto();
        // 1. 根据课程id查询课程基本信息
        CourseBase courseBase = courseBaseMapper.selectById(courseId);
        // 1.1 拷贝属性
        BeanUtils.copyProperties(courseBase, courseBaseInfoDto);
        // 2. 根据课程id查询课程营销信息
        CourseMarket courseMarket = courseMarketMapper.selectById(courseId);
        // 2.1 拷贝属性
        BeanUtils.copyProperties(courseMarket, courseBaseInfoDto);
        // 3. 查询课程分类名称，并设置属性
        // 3.1 根据小分类id查询课程分类对象
        CourseCategory courseCategoryBySt = courseCategoryMapper.selectById(courseBase.getSt());
        // 3.2 设置课程的小分类名称
        courseBaseInfoDto.setStName(courseCategoryBySt.getName());
        // 3.3 根据大分类id查询课程分类对象
        CourseCategory courseCategoryByMt = courseCategoryMapper.selectById(courseBase.getMt());
        // 3.4 设置课程大分类名称
        courseBaseInfoDto.setMtName(courseCategoryByMt.getName());
        // 返回结果
        return courseBaseInfoDto;
    }

    /**
     * 修改课程信息
     *
     * @param editCourseDto 课程信息
     * @return
     */
    @Transactional
    @Override
    public CourseBaseInfoDto updateCourseBase(EditCourseDto editCourseDto) {
        // 获取课程id
        Long courseId = editCourseDto.getId();

        // 更新课程基础信息
        CourseBase courseBase = new CourseBase();
        BeanUtils.copyProperties(editCourseDto, courseBase);
        int courseBaseFlag = courseBaseMapper.updateById(courseBase);

        // 判断更新课程基础信息是否成功
        if (courseBaseFlag != 1) XueChengPlusException.cast("更新课程基础信息失败");

        // 更新课程营销信息
        CourseMarket courseMarket = new CourseMarket();
        BeanUtils.copyProperties(editCourseDto, courseMarket);
        int courseMarketFlag = courseMarketMapper.updateById(courseMarket);

        // 判断更新课程基础信息是否成功
        if (courseMarketFlag != 1) XueChengPlusException.cast("更新课程营销信息失败");

        // 根据课程id查询数据并返回
        return this.getCourseBaseById(courseId);
    }

    /**
     * 删除课程信息
     *
     * @param companyId 机构id
     * @param courseId  课程id
     */
    @Transactional
    @Override
    public void removeCourse(Long companyId, Long courseId) {
        // 获取课程信息
        CourseBase courseBase = courseBaseMapper.selectById(courseId);
        // 判断删除的课程是否是本机构的
        if (!companyId.equals(courseBase.getCompanyId()))
            XueChengPlusException.cast("非本机构的课程禁止删除");

        // 删除课程基础信息
        courseBaseMapper.deleteById(courseId);

        // 删除课程营销信息
        courseMarketMapper.deleteById(courseId);

        // 删除课程计划信息
        LambdaUpdateWrapper<Teachplan> TeachplanUpdateWrapper = new LambdaUpdateWrapper<>();
        TeachplanUpdateWrapper.eq(Teachplan::getCourseId, courseId);
        teachplanMapper.delete(TeachplanUpdateWrapper);

        // 删除课程教师信息
        LambdaUpdateWrapper<CourseTeacher> CourseTeacherUpdateWrapper = new LambdaUpdateWrapper<>();
        CourseTeacherUpdateWrapper.eq(CourseTeacher::getCourseId, courseId);
        courseTeacherMapper.delete(CourseTeacherUpdateWrapper);
    }
}
